package com.app;

import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;

import com.hankcs.hanlp.HanLP;

/**
<!-- 分词 -->
		<dependency>
		   <groupId>com.hankcs</groupId>
		   <artifactId>hanlp</artifactId>
		</dependency><!-- 分词 -->
		<dependency>
		   <groupId>com.hankcs</groupId>
		   <artifactId>hanlp</artifactId>
		</dependency><hanlp.version>portable-1.6.4</hanlp.version>




*/



//汉语言处理 相关的工具类
public final class HanLPUtils {

	// 测试可以设置为true，打印在后台过程
	public static boolean isDebug = false;

	// 需要去除的标点符号
	private static String stopWord = "`~!@#$^&*()=-|{}':;',[\\].<>/?~！￥……&*（）——|{}【】‘’；：”“。，、？";

	// 抽取5个关键字
	private static List<String> getSplitWords(String sentence) {
		return HanLP.extractKeyword(sentence, 5);
	}

	// 抽取所有单词，并且去除标点
	private static List<String> getWords(String sentence) {
		List<String> res = HanLP.segment(sentence).stream()
				.map(t -> t.word)
				.filter(s -> !stopWord.contains(s))
				.collect(Collectors.toList());
		if (isDebug) {
			System.out.println(res);
		}
		return res;
	}

	// 合并分词结果，列出所有的词
	private static List<String> mergeList(
			List<String> list1, List<String> list2) {
		List<String> result = new ArrayList<String>();
		result.addAll(list1);
		result.addAll(list2);
		if (isDebug) {
			System.out.println(result);
		}
		// 去掉重复元素
		for (int i = 0; i < result.size() - 1; i++) {
			for (int j = result.size() - 1; j > i; j--) {
				if (result.get(j).equals(result.get(i))) {
					result.remove(j);
				}
			}
		}
		if (isDebug) {
			System.out.println(result);
		}
		return result;
		// return result.stream().distinct().collect(Collectors.toList());
	}

	// 计算词频；allWords是合并分词得到的词，sentWords是抽取关键字的结果
	private static int[] statistic(List<String> allWords,
			List<String> sentWords) {
		int[] result = new int[allWords.size()];
		for (int i = 0; i < allWords.size(); i++) {
			result[i] = Collections.frequency(sentWords,
					allWords.get(i));
		}

		if (isDebug) {
			System.out.print("[");
			for (int i = 0; i < result.length; i++) {
				System.out.print(result[i] + ",");
			}
			System.out.print("]");
			System.out.println();
		}

		return result;
	}

	// 计算余弦值
	private static double getSimilarity(int[] statistic1,
			int[] statistic2) {
		double dividend = 0;
		double divisor1 = 0;
		double divisor2 = 0;
		for (int i = 0; i < statistic1.length; i++) {
			dividend += statistic1[i] * statistic2[i];
			divisor1 += Math.pow(statistic1[i], 2);
			divisor2 += Math.pow(statistic2[i], 2);
		}

		double res = dividend / (Math.sqrt(divisor1)
				* Math.sqrt(divisor2));
		if (isDebug) {
			System.out.println("余弦值：" + res);
		}
		return res;
	}

	// 转换为百分比
	public static String toNumber(double num) {
		NumberFormat number = NumberFormat
				.getPercentInstance();
		number.setMaximumIntegerDigits(3);
		number.setMaximumFractionDigits(2);
		String strNum = number.format(num);
		if (isDebug) {
			System.out.println("百分比：" + strNum);
		}
		return strNum;
	}

	/**
	 * 获取两个句子的分词后的相似度
	 * 
	 * @param str1
	 * @param str2
	 * @return 差异值为0-1间的数，数值越大相似度越高
	 */
	public static Double getSimilarityBySplit(String str1,
			String str2) {
		// 获取关键词
//		List<String> keywordList1 = getSplitWords(content1);
//		List<String> keywordList2 = getSplitWords(content2);

		// 将两个句子分词
		List<String> keywordList1 = getWords(str1);
		List<String> keywordList2 = getWords(str2);

		// 合并关键词
		List<String> total = mergeList(keywordList1,
				keywordList2);
		// 计算词频
		int[] list1 = statistic(total, keywordList1);
		int[] list2 = statistic(total, keywordList2);

		// 计算余弦值
		Double num = getSimilarity(list1, list2);
		// 转换为百分比
		// String numFormat = toNumber(num);

		return num;
	}

	/**
	 * 获取两个句子的整句的差异值
	 * 
	 * @param str1
	 * @param str2
	 * @return 差异值为0-1间的数，数值越大相似度越高
	 */
	public static double getSimilarity(String target,
			String other) {
		int distance = StringUtils
				.getLevenshteinDistance(target, other);

		double res = 1.0d - ((double) distance / Math
				.max(target.length(), other.length()));
		if (isDebug) {
			System.out.println("差异值：" + res);
		}
		return res;
	}

	public static void main(String[] args)
			throws IOException {
		System.out.println("--------分词对比两句话 start-------");
		String content1 = "社会和谐是中国特色社会主义的本质属性，是国家富强、社会和谐是中国特色社会主义的本质属性民族振兴、人民幸福的重要保证。构建社会主义和谐社会，是我们党以马克思列宁主义、毛泽东思想、邓小平理论和“三个代表”重要思想为指导，全面贯彻落实科学发展观，从中国特色社会主义事业总体布局和全面建设小康社会全局出发提出的重大战略任务，反映了建设富强民主文明和谐的社会主义现代化国家的内在要求，体现了全党全国各族人民的共同愿望。";
		String content2 = "社会和谐是中国特色社会主义的本质属性，是国家富强、社会和谐是中国特色社会主义的本质属性民族振兴、人民幸福的重要保证。社会和谐是我们党不懈奋斗的目标。新中国成立后，我们党为促进社会和谐进行了艰辛探索，积累了正反两方面经验，取得了重要进展。党的十一届三中全会以后，我们党坚定不移地推进改革开放和现代化建设，积极推动经济发展和社会全面进步，为促进社会和谐进行了不懈努力。党的十六大以来，我们党对社会和谐的认识不断深化，明确了构建社会主义和谐社会在中国特色社会主义事业总体布局中的地位，作出一系列决策部署，推动和谐社会建设取得新的成效。经过长期努力，我们拥有了构建社会主义和谐社会的各种有利条件。";
		
		Double num = getSimilarityBySplit(content1, content2);
		System.out.println(num);
		toNumber(num);
		System.out.println("--------分词对比两句话 end---------");
		System.out.println("");
		System.out.println("");
		System.out.println("");
		System.out.println("--------整句对比两句话 start-------");
//		content1 = "1111路面平整路面平整路面平整路面平整路面平整";
//		content2 = "22路面平整路面平整路面平整路面平整路面平平";
		double distance = getSimilarity(content1, content2);
		toNumber(distance);
		System.out.println(distance);
		System.out.println("--------整句对比两句话 end---------");

	}

}
